#include "balancer.h"


Balancer_Define::Balancer_Define(double process_speed,int group_idx)
    :FacilityDefine(
        FacilityType::BALANCER,
        process_speed,
        2,
        1,
        2,
        2,
        group_idx
        ){
    relative_exits.push_back(ExitGate(Coordinate(0,0),gate::Gate_UP));
    relative_exits.push_back(ExitGate(Coordinate(1,0),gate::Gate_UP));
    relative_enters.push_back(EnterGate(Coordinate(0,0),gate::Gate_DOWN));
    relative_enters.push_back(EnterGate(Coordinate(1,0),gate::Gate_DOWN));
}



Balancer::Balancer(FacilityDefine *define, FacilityDirection f_dir, Coordinate coordinate, Cargo_Manager * cargo_manager)
:Facility(define,f_dir,coordinate,cargo_manager){

}
void Balancer::finishProcess(){
    // 平衡的选择
    int i = choose;

    if(incargos[i]){

        if(!outcargos[0]){
            outcargos[0] = incargos[i];
            incargos[i] = null;
            Cargo * c = outcargos[0];
            switch (c->define->cargo_type) {
            case CargoType::COLOR:
                cargo_manager->paintColorCargo(abs_exits[0].position.x,abs_exits[0].position.y,abs_exits[0].direction,(ColorCargo*)c);
                break;
            case CargoType::SHAPE:
                cargo_manager->paintShapeCargo(abs_exits[0].position.x,abs_exits[0].position.y,abs_exits[0].direction,(ShapeCargo*)c);
                break;
            default:
                break;
            }
        }else if(!outcargos[1]){
            outcargos[1] = incargos[i];
            incargos[i] = null;
            Cargo * c = outcargos[1];
            switch (c->define->cargo_type) {
            case CargoType::COLOR:
                cargo_manager->paintColorCargo(abs_exits[1].position.x,abs_exits[1].position.y,abs_exits[1].direction,(ColorCargo*)c);
                break;
            case CargoType::SHAPE:
                cargo_manager->paintShapeCargo(abs_exits[1].position.x,abs_exits[1].position.y,abs_exits[1].direction,(ShapeCargo*)c);
                break;
            default:
                break;
            }
        }
    }
    i ^= 1;
    if(incargos[i]){
        if(!outcargos[1]){
            outcargos[1] = incargos[i];
            incargos[i] = null;
            Cargo * c = outcargos[1];
            switch (c->define->cargo_type) {
            case CargoType::COLOR:
                cargo_manager->paintColorCargo(abs_exits[1].position.x,abs_exits[1].position.y,abs_exits[1].direction,(ColorCargo*)c);
                break;
            case CargoType::SHAPE:
                cargo_manager->paintShapeCargo(abs_exits[1].position.x,abs_exits[1].position.y,abs_exits[1].direction,(ShapeCargo*)c);
                break;
            default:
                break;
            }
        }
        else if(!outcargos[0]){
            outcargos[0] = incargos[i];
            incargos[i] = null;
            Cargo * c = outcargos[0];
            switch (c->define->cargo_type) {
            case CargoType::COLOR:
                cargo_manager->paintColorCargo(abs_exits[0].position.x,abs_exits[0].position.y,abs_exits[0].direction,(ColorCargo*)c);
                break;
            case CargoType::SHAPE:
                cargo_manager->paintShapeCargo(abs_exits[0].position.x,abs_exits[0].position.y,abs_exits[0].direction,(ShapeCargo*)c);
                break;
            default:
                break;
            }
        }
    }
    choose = i;
    sendCargo();
    Facility::finishProcess();
}

bool Balancer::outEmpty(){
    for(int i = 0; i < outcargos.size(); ++i){
        if(!outcargos[i]) return true;
    }
    return false;
}
bool Balancer::inEmpty(){
    for(int i = 0; i < incargos.size(); ++i){
        if(incargos[i]) return false;
    }
    return true;
}
